package cn.ibizlab.util.adapter.service.impl;

import cn.ibizlab.util.adapter.service.SysRuntimeModelService;
import cn.ibizlab.util.helper.BeanCache;
import cn.ibizlab.util.helper.StringAdvUtils;
import lombok.extern.slf4j.Slf4j;
import net.ibizsys.central.ISystemRuntime;
import net.ibizsys.central.cloud.core.IServiceSystemRuntime;
import net.ibizsys.central.cloud.core.ServiceSystemRuntime;
import net.ibizsys.central.cloud.core.spring.rt.ServiceHub;
import net.ibizsys.central.dataentity.IDataEntityRuntime;
import net.ibizsys.central.dataentity.service.IDEServiceAPIRuntime;
import net.ibizsys.central.service.ISysServiceAPIRuntime;
import net.ibizsys.model.dataentity.action.IPSDEAction;
import net.ibizsys.model.dataentity.service.IPSDEServiceAPIMethod;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

/**
 * adapter 模型服务对象：用于初始化系统模型构造runtime服务
 */
@Slf4j
@Service
public class DefaultSysRuntimeModelService implements SysRuntimeModelService {

    @Autowired
    @Lazy
    ServiceHub serviceHub;
    ISystemRuntime systemRuntime;
    @Value("${ibiz.runtime.mapUnderscore2camelCase:false}")
    private boolean mapUnderscore2camelCase;

    @Override
    public void init() {}

    @Override
    public void reload() {}

    @Override
    public ISystemRuntime getSystemRuntime() {
        if(systemRuntime == null)
            this.systemRuntime = serviceHub.getSystemRuntime(ServiceSystemRuntime.class, false);
        return systemRuntime;
    }

    public void setSystemRuntime(ISystemRuntime systemRuntime) {
        this.systemRuntime = systemRuntime;
    }

    /**
     * 获取实体运行时对象
     * @param entityName
     * @param bTryMode
     * @return
     */
    @Override
    public IDataEntityRuntime getDataEntityRuntime(String entityName, boolean bTryMode) {
        IDataEntityRuntime dataEntityRuntime = getSystemRuntime().getDataEntityRuntime(entityName,true);
        if(dataEntityRuntime == null && mapUnderscore2camelCase){
            dataEntityRuntime = getSystemRuntime().getDataEntityRuntime(StringAdvUtils.underscore(entityName),true);
        }
        if (dataEntityRuntime == null && !bTryMode)
            throw new RuntimeException(String.format("无法获取指定实体[%1$s]模型对象", entityName));

        return  dataEntityRuntime;
    }

    /**
     * 获取实体运行时对象
     * @param cls
     * @return
     */
    @Override
    public IDataEntityRuntime getDataEntityRuntime(Class cls ,boolean bTryMode) {

        BeanCache.BeanSchema entitySchema = BeanCache.get(cls);
        if(entitySchema == null)
            throw new RuntimeException(String.format("未查询到实体类[%1$s]信息",cls.getSimpleName()));

        IDataEntityRuntime dataEntityRuntime = getDataEntityRuntime(entitySchema.getCodeName(),true);
        if(dataEntityRuntime == null){
            dataEntityRuntime = getDataEntityRuntime(entitySchema.getName(),bTryMode);
        }
        return dataEntityRuntime;
    }

    /**
     * 获取实体服务api运行时对象
     * @param iSysServiceAPIRuntime
     * @param entityName
     * @param bTryMode
     * @return
     */
    @Override
    public IDEServiceAPIRuntime getDEServiceAPIRuntime(ISysServiceAPIRuntime iSysServiceAPIRuntime, String entityName, boolean bTryMode) {
        IDEServiceAPIRuntime iDEServiceAPIRuntime = iSysServiceAPIRuntime.getDEServiceAPIRuntime(entityName, true);
        if (iDEServiceAPIRuntime == null && mapUnderscore2camelCase) {
            iDEServiceAPIRuntime =iSysServiceAPIRuntime.getDEServiceAPIRuntime(StringAdvUtils.underscore(entityName), true);
        }

        if(iDEServiceAPIRuntime == null && !bTryMode)
            throw new RuntimeException(String.format("获取实体[%1$s]的服务运行时对象失败", entityName));

        return iDEServiceAPIRuntime;
    }

    /**
     * 获取实体服务api方法对象
     * @param iDEServiceAPIRuntime
     * @param actionName
     * @param bTryMode
     * @return
     */
    @Override
    public IPSDEServiceAPIMethod getPSDEServiceAPIMethod(IDEServiceAPIRuntime iDEServiceAPIRuntime, String actionName, boolean bTryMode) {
        IPSDEServiceAPIMethod ipsdeServiceAPIMethod = iDEServiceAPIRuntime.getPSDEServiceAPIMethod(actionName, true);
        if(ipsdeServiceAPIMethod == null && mapUnderscore2camelCase){
            ipsdeServiceAPIMethod = iDEServiceAPIRuntime.getPSDEServiceAPIMethod(StringAdvUtils.underscore(actionName), true);
        }

        if(ipsdeServiceAPIMethod == null && !bTryMode)
            throw new RuntimeException(String.format("获取实体[%1$s]的服务方法对象失败", actionName));

        return ipsdeServiceAPIMethod;
    }


    /**
     * 获取实体行为
     * @param dataEntityRuntime
     * @param actionName
     * @param bTryMode
     * @return
     */
    @Override
    public IPSDEAction getPSDEAction(IDataEntityRuntime dataEntityRuntime, String actionName , boolean bTryMode) {
        IPSDEAction ipsdeAction = dataEntityRuntime.getPSDEAction(actionName);
        if(ipsdeAction == null && mapUnderscore2camelCase){
            ipsdeAction = dataEntityRuntime.getPSDEAction(StringAdvUtils.underscore(actionName));
        }

        if (ipsdeAction == null && !bTryMode)
            throw new RuntimeException(String.format("获取实体[%1$s]行为[%2$s]对象失败", dataEntityRuntime.getName(), actionName));

        return ipsdeAction;
    }

}
